package timingwheel

import (
	"container/list"
	"sync"
)

type Grid struct {
	lock     sync.Mutex
	taskList *list.List
}

func (g *Grid) Run() {
	g.lock.Lock()
	defer g.lock.Unlock()
	if g.taskList.Len() == 0 {
		return
	}
	for {
		e := g.taskList.Front()
		t := e.Value.(*Task)
		g.taskList.Remove(e)
		if !t.IsCancel() {
			t.Run()
		}
		if g.taskList.Len() == 0 {
			break
		}
	}
}

func (g *Grid) PushTask(task *Task) {
	g.lock.Lock()
	defer g.lock.Unlock()
	g.taskList.PushBack(task)
}

func (g *Grid) TaskCount() int {
	return g.taskList.Len()
}

// 提供外部遍历任务
func (g *Grid) IterateTask(callback func(task *Task)) {
	g.lock.Lock()
	defer g.lock.Unlock()
	for e := g.taskList.Front(); e != nil; e = e.Next() {
		task := e.Value.(*Task)
		if !task.IsCancel() {
			callback(task)
		}
	}
}

// 切断任务引用
func (g *Grid) ClearTask() {
	g.taskList = list.New()
}

func NewGrid() *Grid {
	return &Grid{
		lock:     sync.Mutex{},
		taskList: list.New(),
	}
}
